﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using PSE.ProcessManager.Entity;

namespace PSE.ProcessManager.ResourceAccess.FileSystemProvider
{
    public class ProcessResourceAccess : BaseFileAccess
    {
        private static Mutex _mtxLock = new Mutex(false, "PSE.ProcessManager.ResourceAccess.FileSystemProvider.Process.MtxLock");

        private string _filePath;
        public ProcessResourceAccess(string filePath)
        {
            _filePath = filePath;
        }

        public List<ProcessEntity> GetAll()
        {
            List<ProcessEntity> ret = base.LoadFromXmlFile<List<ProcessEntity>>(_filePath);
            if (ret == null)
                ret = new List<ProcessEntity>();

            return ret;
        }

        public ProcessEntity GetOne(int processId)
        {
            List<ProcessEntity> processes = GetAll();
            if (processes.Count > 0)
            {
                return processes.Find(p => p.Id == processId);
            }
            else
                return null;
        }

        public void Update(ProcessEntity process)
        {
            try
            {
                _mtxLock.WaitOne();

                //recuperar todas as mensagens
                List<ProcessEntity> processsInFile = GetAll();

                int index = processsInFile.FindIndex(m => m.Id == process.Id);
                if (index >= 0)
                {
                    processsInFile[index] = process;
                    //salvar
                    base.SaveToXmlFile(_filePath, processsInFile);
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                _mtxLock.ReleaseMutex();
            }
        }

        public void Insert(ProcessEntity entity)
        {
            try
            {
                _mtxLock.WaitOne();

                //recuperar todas as mensagens
                List<ProcessEntity> processsInFile = GetAll();

                //recuperar o id da mensagem
                entity.Id = GetNextProcessId(processsInFile);

                //adicionar a lista
                processsInFile.Add(entity);

                //salvar
                base.SaveToXmlFile(_filePath, processsInFile);
            }
            catch
            {
                throw;
            }
            finally
            {
                _mtxLock.ReleaseMutex();
            }
        }

        public int GetNextProcessId(List<ProcessEntity> processsInfFile)
        {
            if (processsInfFile.Count == 0)
                return 1;
            else
            {
                processsInfFile.Sort(new Comparison<ProcessEntity>(CompareProcessById));
                return processsInfFile.Last<ProcessEntity>().Id.GetValueOrDefault() + 1;
            }
        }

        private int CompareProcessById(ProcessEntity a, ProcessEntity b)
        {
            return a.Id.GetValueOrDefault().CompareTo(b.Id.GetValueOrDefault());
        }

        public void SaveToFile(List<ProcessEntity> listProcess)
        {
            try
            {
                _mtxLock.WaitOne();

                if (listProcess != null)
                    listProcess.Sort(new Comparison<ProcessEntity>(CompareProcessById));

                //salvar
                base.SaveToXmlFile(_filePath, listProcess);
            }
            catch
            {
                throw;
            }
            finally
            {
                _mtxLock.ReleaseMutex();
            }
        }
    }
}
